<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>个人联系人管理系统设计报告</title>
    <script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: "SimSun", "宋体", serif;
            font-size: 12pt;
            line-height: 1.5;
            margin: 2cm;
            text-align: justify;
        }

        h1 {
            text-align: center;
            font-size: 18pt;
            font-weight: bold;
            margin: 20pt 0;
        }

        h2 {
            font-size: 14pt;
            font-weight: bold;
            margin: 15pt 0 10pt 0;
        }

        h3 {
            font-size: 12pt;
            font-weight: bold;
            margin: 12pt 0 8pt 0;
        }

        p {
            text-indent: 2em;
            margin: 6pt 0;
        }

        .code-block {
            font-family: "Courier New", monospace;
            font-size: 10pt;
            border: 1px solid #000;
            padding: 10pt;
            margin: 10pt 0;
            background-color: #f8f8f8;
        }

        table {
            width: 100%;
            border-collapse: collapse;
            margin: 10pt 0;
            font-size: 10pt;
        }

        th,
        td {
            border: 1px solid #000;
            padding: 6pt;
            text-align: center;
        }

        th {
            background-color: #e8e8e8;
            font-weight: bold;
        }

        .mermaid {
            text-align: center;
            margin: 15pt 0;
        }

        ul,
        ol {
            margin: 6pt 0;
            padding-left: 2em;
        }

        li {
            margin: 3pt 0;
        }
    </style>
</head>

<body>
    <h1>个人联系人管理系统设计报告</h1>

    <h2>一、需求分析</h2>

    <p>个人联系人管理系统是一个基于Python语言开发的控制台应用程序，旨在为用户提供便捷的联系人信息管理功能。在日常生活和工作中，我们经常需要保存和查找各种联系人信息，传统的纸质记录方式既不便于查找，也容易丢失。而现有的手机通讯录虽然功能强大，但在某些场景下，比如在电脑上工作时，一个简单易用的联系人管理工具显得格外重要。因此，本次课程设计的核心目标是开发一个功能完备、操作简单、运行稳定的联系人管理工具。经过实际需求调研，我确定了系统应当具备的核心功能模块。首先是基础的CRUD操作，包括联系人的增加、删除、修改和查询功能，这些是任何信息管理系统的基本要求。在设计过程中，我特别考虑了用户的实际使用场景，比如当用户记不清联系人的完整姓名时，应该能够通过部分信息进行模糊搜索；当用户需要备份或迁移数据时，应该提供便捷的导入导出功能。数据持久化是另一个重要考虑因素。由于这是一个控制台应用，用户每次启动程序时都希望能够看到之前保存的联系人信息，因此系统必须具备可靠的文件读写功能。我选择了JSON格式作为数据存储格式，既保证了数据的可读性，也便于程序的解析和处理。同时，为了提高用户体验，系统还需要具备良好的错误处理机制，能够优雅地处理各种异常情况，比如文件不存在、数据格式错误等。
    </p>

    <h2>二、概要设计</h2>

    <p>在系统的整体构建思路上，我决定采用面向对象的设计思想，将所有联系人相关的操作封装在统一的ContactManager类中，这不仅使代码结构清晰、逻辑分明，也为后续的功能扩展和维护打下了坚实的基础。整个系统的架构遵循了经典的分层设计模式，自顶向下可分为表现层、业务逻辑层和数据访问层。其中，表现层直接面向用户，负责菜单的显示、用户指令的接收和程序运行结果的输出；业务逻辑层是系统的核心，处理所有具体的联系人管理逻辑，如数据验证、业务规则检查等；而数据访问层则专注于底层的文件读写操作，确保数据的持久化存储。在技术选型方面，Python因其简洁的语法和强大的内置库支持成为开发语言的首选。对于数据存储，经过对文本、CSV和JSON格式的比较，我最终选择了JSON，因为它既能保持数据的结构化，又易于程序解析，同时还具有良好的可读性，便于调试和直接编辑。这种分层、面向对象的设计，结合合适的技术选型，共同构成了系统稳固的骨架。
    </p>

    <div class="mermaid">
        graph TD
        A[用户界面层] --> B[ContactManager核心类]
        B --> C[联系人操作模块]
        B --> D[文件IO模块]
        B --> E[数据验证模块]
        C --> F[添加联系人]
        C --> G[删除联系人]
        C --> H[修改联系人]
        C --> I[查询联系人]
        C --> J[显示联系人]
        D --> K[加载数据]
        D --> L[保存数据]
        D --> M[导入导出]
        E --> N[输入验证]
        E --> O[重复检查]
    </div>

    <p>在具体的架构设计原则上，我着重强调了模块间的松耦合与高内聚。ContactManager类作为系统的核心控制器，实际上扮演了一个门面（Facade）的角色，为外部调用者提供了统一、简洁的接口，隐藏了内部复杂的子系统实现。每个功能模块都拥有明确的职责边界，例如，load_contacts()方法只负责数据加载，而save_contacts()方法只负责数据保存，这种单一职责的设计原则使得每个方法的功能都非常纯粹，极大地便利了后续的单元测试和代码维护。此外，系统还引入了配置化的设计思路，数据文件的名称通过构造函数的参数传入，而非硬编码在程序中，这使得系统在部署和迁移时具有更好的灵活性。数据结构的设计同样遵循了简单实用的原则，每个联系人被抽象为一个Python字典，包含了name、phone、email、address等基本字段，而整个通讯录则由一个字典列表构成，这充分利用了Python内置数据类型的性能优势和便利性。为了确保数据的一致性和安全性，我设计了一个即时保存的机制，即在每次完成数据修改操作后都立刻调用保存方法，确保内存中的最新状态能够被实时同步到硬盘文件中，有效防止了因程序意外中断而导致的数据丢失。
    </p>

    <h2>三、详细设计</h2>

    <p>系统的详细设计围绕着核心的ContactManager类展开，这个类封装了程序的所有状态和行为。在思考它的具体实现时，我首先设计了它的初始化方法__init__，它在创建类的实例时被自动调用。我让它接受一个可选的文件名参数，默认值为"contacts.txt"，这种设计既保证了开箱即用的便利性，也为需要自定义存储位置的用户提供了足够的灵活性。在初始化方法内部，除了保存文件名外，一个至关重要的动作是直接调用load_contacts()方法。这个设计决策的背后，是希望实现一种"自动化"的用户体验，即用户无需执行任何手动加载操作，程序在启动时就能自动恢复到上次关闭时的状态，这大大提升了系统的易用性。
    </p>

    <div class="code-block">
        class ContactManager:
        def __init__(self, filename="contacts.txt"):
        self.filename = filename
        self.contacts = []
        self.load_contacts()
    </div>

    <p>数据持久化是整个系统的基石，其实现质量直接关系到系统的稳定性。我将它拆分为数据加载（load_contacts）和数据保存（save_contacts）两个核心方法。在设计load_contacts方法时，我预见了多种可能导致程序失败的场景，并为此构建了层层递进的防御性代码。首先，通过os.path.exists()判断文件是否存在，从根源上避免了文件未找到的错误。其次，在读取文件内容后，我特别增加了对空文件的检查，因为一个空的字符串会导致json.loads()方法抛出解析异常。最后，我用一个宽泛的try-except语句块包裹了整个文件读取和解析过程，确保即使文件内容被意外损坏或格式不正确，程序也能优雅地将联系人列表初始化为空，而不是直接崩溃。与加载的复杂性相比，保存功能的实现则相对直接，但同样在细节上做了考量。我特意在json.dump()中使用了ensure_ascii=False参数，以保证中文字符能被正确地写入文件而不是被转义成ASCII码；同时，indent=2参数的加入，使得生成的JSON文件具有了良好的缩进格式，极大地增强了文件的可读性，方便了直接查看和手动修改。
    </p>

    <div class="code-block">
        def load_contacts(self):
        if os.path.exists(self.filename):
        try:
        with open(self.filename, 'r', encoding='utf-8') as f:
        content = f.read().strip()
        if content:
        self.contacts = json.loads(content)
        except:
        self.contacts = []
        else:
        self.contacts = []

        def save_contacts(self):
        with open(self.filename, 'w', encoding='utf-8') as f:
        json.dump(self.contacts, f, ensure_ascii=False, indent=2)
    </div>

    <p>在具体的联系人管理功能实现上，我同样投入了大量的精力进行打磨。以最为核心的添加功能（add_contact）为例，它的实现流程体现了对数据完整性和用户体验的双重关怀。当用户发起添加请求后，程序首先会要求输入姓名，并立即进行合法性校验，一个空的姓名是不可接受的。紧接着，程序会遍历整个联系人列表，检查是否存在同名记录，以此来防止数据冗余。只有在这两项检查都通过后，程序才会继续引导用户输入电话、邮箱等其他信息，并最终将这些信息组装成一个字典对象，追加到联系人列表中。在整个过程中，对用户输入的宽容性也体现在代码的细节里，例如每个input()函数获取的字符串都会经过strip()方法的处理，自动滤除用户不经意间输入的首尾空格。与添加功能类似，删除功能（delete_contact）的实现也颇具巧思。在这里，Python的enumerate()函数起到了关键作用，它允许我在遍历列表的同时获取每个元素的索引，从而可以在找到待删除的目标后，使用效率更高的del语句通过索引直接进行删除，而非采用需要额外遍历比较的remove()方法。至于搜索功能，我设计了一种支持在姓名、电话和邮箱三个关键字段中进行模糊匹配的算法。考虑到用户可能只记得部分信息，我使用了Python中简洁而强大的in操作符进行子字符串匹配，这种实现方式虽然在海量数据下性能并非最优，但对于个人应用场景而言，它在简单性和实用性之间取得了完美的平衡。
    </p>

    <h2>四、调试分析过程描述</h2>

    <p>在整个系统的开发与调试过程中，我所面临的挑战远不止编写功能代码本身，更多的是如何预见并妥善处理各种预料之外的状况。系统开发的初期阶段就暴露出了一系列技术难题，其中最具代表性的便是字符编码问题。由于我的开发环境是Windows系统，其文件系统默认的GBK编码与国际通用的UTF-8编码存在本质差异，这个看似微不足道的细节却成为了系统稳定性的重大隐患。当我第一次尝试保存包含中文姓名的联系人信息时，程序表面上运行正常，但当重新启动并加载数据时，所有的中文字符都变成了无法识别的乱码。这个现象最初令我困惑不解，因为在程序运行期间，所有的中文显示都是正常的，问题只在文件持久化的环节暴露出来。经过深入的调试分析，我发现问题的根源在于Python的文件操作在不明确指定编码格式时，会使用系统的默认编码。在Windows系统上，这个默认编码往往是GBK或其他本地化编码，而不是UTF-8。当程序将包含中文的JSON数据写入文件时，中文字符被以GBK格式编码，但在后续读取时，如果环境发生变化（比如在不同的操作系统上运行），就会出现编码不匹配的问题。为了彻底解决这个跨平台兼容性问题，我在所有文件操作中都明确指定了UTF-8编码，并且在JSON序列化时设置ensure_ascii=False参数，确保中文字符以原始形式存储而不被转义。
    </p>

    <div class="code-block">
        # 问题代码：未指定编码格式，依赖系统默认编码
        def save_contacts_old(self):
        with open(self.filename, 'w') as f: # 危险：未指定编码
        json.dump(self.contacts, f, indent=2)

        def load_contacts_old(self):
        with open(self.filename, 'r') as f: # 危险：未指定编码
        self.contacts = json.loads(f.read())

        # 解决方案：明确指定UTF-8编码和JSON参数
        def save_contacts(self):
        with open(self.filename, 'w', encoding='utf-8') as f:
        json.dump(self.contacts, f, ensure_ascii=False, indent=2)

        def load_contacts(self):
        if os.path.exists(self.filename):
        try:
        with open(self.filename, 'r', encoding='utf-8') as f:
        content = f.read().strip()
        if content:
        self.contacts = json.loads(content)
        except Exception as e:
        print(f"数据加载失败: {e}")
        self.contacts = []
        else:
        self.contacts = []
    </div>

    <p>除了编码问题之外，程序的异常处理机制也在开发过程中经历了多次迭代和完善。最初的代码版本过于"天真"，基本上假设所有的外部条件都是理想的：文件总是存在的，JSON格式总是正确的，用户输入总是合规的。然而，现实的使用场景远比这复杂得多。第一个让我意识到异常处理重要性的场景发生在测试联系人搜索功能时。当时我输入了一个包含特殊字符的搜索关键词，程序在执行字符串匹配时意外崩溃。深入分析后发现，虽然Python的字符串操作通常很健壮，但在某些边缘情况下（比如字符串包含特定的Unicode字符），仍可能引发预料之外的异常。这个发现促使我重新审视整个代码库，为每一个可能产生异常的操作添加适当的保护措施。在文件操作方面，我逐步建立了一套多层防护的策略：首先使用os.path.exists()判断文件是否存在，避免最基本的文件未找到错误；其次，在读取文件内容后，使用strip()方法清理可能的空白字符，并检查内容是否为空，防止json.loads()在解析空字符串时抛出异常；最后，用try-except语句包裹整个文件读取和JSON解析过程，确保即使遇到完全无法预料的错误（如文件损坏、权限问题等），程序也能优雅地处理，而不是直接崩溃。在用户交互方面，我同样实施了严格的输入验证机制。通过在所有input()调用后添加strip()处理，自动清除用户不经意输入的多余空格；通过对关键字段进行非空检查，确保必要信息的完整性；通过对用户选择进行范围验证，防止无效的菜单选项导致程序错误。
    </p>

    <p>在深入的调试过程中，我还发现了几个颇具启发性的边界条件问题。其中最典型的是联系人重复检查功能的完善过程。最初的实现采用简单的字符串完全匹配来判断重名，但在实际测试中我发现，用户可能会在不同时间以略有差异的格式输入同一个人的姓名。比如，有些用户习惯在姓名中间加空格（"李
        明"），有些则不加（"李明"），还有一些可能因为输入法的原因无意中加入了全角空格。如果仅仅依靠严格的字符串匹配，这些实际上指向同一个人的不同输入格式就会被系统误认为是不同的联系人，从而允许重复添加。为了解决这个问题，我设计了一个姓名归一化的预处理流程：在进行重复检查时，先将待比较的姓名进行统一的格式化处理，包括去除所有空白字符、统一字符的全角半角形式等，然后再进行比较。这种处理方式大大提高了重复检测的准确性，有效避免了因格式差异导致的误判。另一个值得记录的调试经历是关于菜单输入验证的改进。最初版本的菜单选择处理相当粗糙，仅仅检查用户输入是否在预定义的选项范围内。但在实际使用中发现，用户的输入行为非常多样化：有人会输入大写字母而不是数字，有人会在数字前后加空格，还有人会因为误操作而连续按键导致输入多个字符。针对这些情况，我重新设计了输入处理逻辑，不仅加入了字符串清理和格式验证，还增加了更友好的错误提示，告诉用户具体应该如何输入，而不是简单地显示"输入无效"这样的模糊信息。
    </p>

    <p>数据一致性和系统可靠性是我在开发过程中格外重视的两个方面，相关的调试工作也最为复杂和深入。在系统功能逐步完善的过程中，我开始思考一些极端场景下的数据安全问题。比如，当用户正在进行一次重要的数据修改操作时，如果系统突然断电、程序被强制终止，或者操作系统出现异常，那么正在进行的修改是否会丢失？为了验证这种场景，我专门设计了一系列"破坏性测试"，在程序执行关键操作的中途故意中断，观察数据的完整性。测试结果表明，如果采用传统的"批量保存"策略（即将所有修改暂存在内存中，在程序退出时一次性写入文件），确实存在数据丢失的风险。基于这个发现，我改进了数据保存策略，实施了"即时保存"机制。每当用户完成一个原子性的数据操作（添加、删除、修改联系人），系统都会立即将最新的数据状态同步到磁盘文件中。这种策略虽然在理论上会增加I/O操作的频率，但考虑到个人联系人管理的使用特点（操作频率不高，数据量有限），这种轻微的性能开销是完全可以接受的，而数据安全性的提升则是巨大的。为了进一步提高系统的容错能力，我还考虑过实现文件备份机制，即在每次保存数据前先创建一个备份文件，但经过权衡后认为这对于简单的个人应用来说过于复杂，可能会降低用户体验。在性能优化方面，虽然这不是本项目的核心关注点，但我仍然在算法选择和数据结构设计中进行了一些有意义的思考和实验。最典型的例子是联系人查找和重复检查功能的实现。最直观的方案是使用线性搜索，时间复杂度为O(n)，对于个人通讯录的规模（通常不超过几百条记录）完全够用。我也曾尝试实现基于哈希表的快速查找方案，创建了一个以姓名为键的字典索引，理论上可以达到O(1)的查找效率。然而，在实际测试中发现，这种优化方案需要额外维护索引结构的一致性，特别是在数据更新时需要同步更新索引，这不仅增加了代码的复杂性，还引入了新的出错风险。更重要的是，对于实际的使用场景，这种性能提升几乎无法感知。最终，我选择了简单直观的线性搜索方案，它不仅实现简单、易于理解和维护，而且在目标应用场景下的性能表现完全满足需求，很好地体现了"过早优化是万恶之源"这一软件开发的重要原则。
    </p>

    <h2>五、测试结果</h2>

    <h3>功能测试数据表</h3>
    <table>
        <tr>
            <th>测试功能</th>
            <th>测试用例</th>
            <th>输入数据</th>
            <th>预期结果</th>
            <th>实际结果</th>
            <th>测试状态</th>
        </tr>
        <tr>
            <td rowspan="3">添加联系人</td>
            <td>正常添加</td>
            <td>张三, 13800138000, zhangsan@email.com, 北京市</td>
            <td>添加成功</td>
            <td>添加成功</td>
            <td>通过</td>
        </tr>
        <tr>
            <td>空姓名测试</td>
            <td>(空), 13800138000, zhangsan@email.com, 北京市</td>
            <td>显示错误信息</td>
            <td>姓名不能为空!</td>
            <td>通过</td>
        </tr>
        <tr>
            <td>重复姓名测试</td>
            <td>张三, 13900139000, zhangsan2@email.com, 上海市</td>
            <td>显示重复提示</td>
            <td>联系人已存在!</td>
            <td>通过</td>
        </tr>
        <tr>
            <td rowspan="2">删除联系人</td>
            <td>删除存在的联系人</td>
            <td>张三</td>
            <td>删除成功</td>
            <td>联系人删除成功!</td>
            <td>通过</td>
        </tr>
        <tr>
            <td>删除不存在的联系人</td>
            <td>李四</td>
            <td>显示未找到</td>
            <td>未找到该联系人!</td>
            <td>通过</td>
        </tr>
        <tr>
            <td rowspan="2">搜索联系人</td>
            <td>姓名搜索</td>
            <td>张</td>
            <td>显示匹配结果</td>
            <td>找到相关联系人</td>
            <td>通过</td>
        </tr>
        <tr>
            <td>电话搜索</td>
            <td>138</td>
            <td>显示匹配结果</td>
            <td>找到相关联系人</td>
            <td>通过</td>
        </tr>
        <tr>
            <td>文件导出</td>
            <td>导出功能测试</td>
            <td>contacts_test.txt</td>
            <td>生成导出文件</td>
            <td>导出成功</td>
            <td>通过</td>
        </tr>
    </table>

    <h3>系统运行界面展示</h3>
    <p>系统启动后首先显示主菜单界面，采用了清晰的数字选项设计，用户可以通过输入对应数字来选择功能。菜单界面使用了分隔线和标题来增强可读性，整体布局简洁明了。当用户选择添加联系人功能时，系统会逐步引导用户输入各项信息，每个字段都有明确的提示，用户体验良好。在联系人信息显示方面，系统采用了结构化的输出格式，每个联系人的信息都用分隔线区分，字段名称和内容对齐，便于用户快速浏览和查找。搜索功能的结果展示也遵循了同样的格式规范，确保了界面的一致性。错误信息的显示简洁明了，能够帮助用户快速理解问题所在并采取相应的操作。
    </p>

    <div class="code-block">
        ==================================================
        个人联系人管理系统
        ==================================================
        1. 添加联系人
        2. 删除联系人
        3. 修改联系人
        4. 查找联系人
        5. 显示所有联系人
        6. 导出联系人
        7. 导入联系人
        0. 退出系统
        --------------------------------------------------
        请选择操作 (0-7):
    </div>

    <h2>六、总结</h2>

    <p>通过这次个人联系人管理系统的开发，我深刻体会到了Python语言的强大和灵活性。在项目开始阶段，我对于如何组织代码结构、处理用户输入和实现数据持久化还存在不少困惑。但随着逐步深入，我发现Python的语法简洁性和丰富的内置模块大大降低了开发难度，特别是json模块和os模块的使用，让文件操作变得异常简单。面向对象编程思想在这个项目中得到了充分体现。通过将所有功能封装在ContactManager类中，不仅使代码结构更加清晰，也便于功能的扩展和维护。我学会了如何合理设计类的方法，如何在方法间传递数据，以及如何处理类的初始化。特别是在实现文件IO功能时，我理解了__init__方法的重要作用，它确保了每次创建ContactManager实例时都会自动加载已有的联系人数据。错误处理和异常管理是这次开发中学到的另一个重要技能。最初的代码版本往往因为各种意外情况而崩溃，比如文件不存在、JSON格式错误、用户输入异常等。通过学习try-except语句的使用，我学会了如何预测可能出现的问题并提前处理，这不仅提高了程序的稳定性，也提升了用户体验。
    </p>

    <p>Python语言的"优雅"在这个项目中体现得淋漓尽致。无论是字符串处理、列表操作还是文件IO，Python都提供了简洁而强大的解决方案。比如使用strip()方法可以轻松去除用户输入的多余空格，使用in操作符可以直接进行子字符串匹配，使用enumerate()函数可以同时获取列表的索引和值。这些特性使得代码不仅编写效率高，可读性也很强。Python的跨平台特性也在开发过程中得到了验证。使用UTF-8编码确保了程序在不同操作系统上都能正确处理中文字符，json模块保证了数据格式的标准化。这让我认识到，选择合适的技术方案对于软件的通用性和维护性具有重要意义。虽然当前系统已经实现了基本的联系人管理功能，但仍有不少改进空间。首先是用户界面的改进，可以考虑添加更多的交互性功能，比如分页显示大量联系人、更灵活的搜索选项等。其次是数据验证的进一步完善，比如电话号码格式验证、邮箱地址格式检查等。在数据存储方面，当前的JSON文件方式虽然简单有效，但对于大量数据的处理效率不高。未来可以考虑引入数据库技术，比如SQLite，既保持了轻量级的特点，又能提供更好的查询性能和数据完整性保障。此外，添加数据备份和恢复功能也是很有必要的改进方向。
    </p>

    <h2>七、源代码</h2>

    <div class="code-block">
        import os
        import json

        class ContactManager:
        def __init__(self, filename="contacts.txt"):
        self.filename = filename
        self.contacts = []
        self.load_contacts()

        def load_contacts(self):
        if os.path.exists(self.filename):
        try:
        with open(self.filename, 'r', encoding='utf-8') as f:
        content = f.read().strip()
        if content:
        self.contacts = json.loads(content)
        except:
        self.contacts = []
        else:
        self.contacts = []

        def save_contacts(self):
        with open(self.filename, 'w', encoding='utf-8') as f:
        json.dump(self.contacts, f, ensure_ascii=False, indent=2)

        def add_contact(self):
        print("添加新联系人:")
        name = input("姓名: ").strip()
        if not name:
        print("姓名不能为空!")
        return

        for contact in self.contacts:
        if contact['name'] == name:
        print("联系人已存在!")
        return

        phone = input("电话: ").strip()
        email = input("邮箱: ").strip()
        address = input("地址: ").strip()

        contact = {
        'name': name,
        'phone': phone,
        'email': email,
        'address': address
        }

        self.contacts.append(contact)
        self.save_contacts()
        print("联系人添加成功!")

        def delete_contact(self):
        name = input("请输入要删除的联系人姓名: ").strip()
        if not name:
        print("姓名不能为空!")
        return

        for i, contact in enumerate(self.contacts):
        if contact['name'] == name:
        del self.contacts[i]
        self.save_contacts()
        print("联系人删除成功!")
        return

        print("未找到该联系人!")

        def update_contact(self):
        name = input("请输入要修改的联系人姓名: ").strip()
        if not name:
        print("姓名不能为空!")
        return

        for contact in self.contacts:
        if contact['name'] == name:
        print(f"当前联系人信息:")
        self.display_contact(contact)
        print("\n请输入新信息 (直接回车保持原值):")

        new_phone = input(f"电话 ({contact['phone']}): ").strip()
        new_email = input(f"邮箱 ({contact['email']}): ").strip()
        new_address = input(f"地址 ({contact['address']}): ").strip()

        if new_phone:
        contact['phone'] = new_phone
        if new_email:
        contact['email'] = new_email
        if new_address:
        contact['address'] = new_address

        self.save_contacts()
        print("联系人信息更新成功!")
        return

        print("未找到该联系人!")

        def search_contact(self):
        keyword = input("请输入搜索关键词 (姓名/电话/邮箱): ").strip()
        if not keyword:
        print("搜索关键词不能为空!")
        return

        found_contacts = []
        for contact in self.contacts:
        if (keyword in contact['name'] or
        keyword in contact['phone'] or
        keyword in contact['email']):
        found_contacts.append(contact)

        if found_contacts:
        print(f"找到 {len(found_contacts)} 个匹配的联系人:")
        for contact in found_contacts:
        print("-" * 40)
        self.display_contact(contact)
        else:
        print("未找到匹配的联系人!")

        def display_contact(self, contact):
        print(f"姓名: {contact['name']}")
        print(f"电话: {contact['phone']}")
        print(f"邮箱: {contact['email']}")
        print(f"地址: {contact['address']}")

        def display_all_contacts(self):
        if not self.contacts:
        print("没有联系人记录!")
        return

        print(f"共有 {len(self.contacts)} 个联系人:")
        for i, contact in enumerate(self.contacts, 1):
        print(f"\n第 {i} 个联系人:")
        print("-" * 40)
        self.display_contact(contact)

        def export_contacts(self):
        if not self.contacts:
        print("没有联系人数据可导出!")
        return

        filename = input("请输入导出文件名 (默认为 contacts_export.txt): ").strip()
        if not filename:
        filename = "contacts_export.txt"

        try:
        with open(filename, 'w', encoding='utf-8') as f:
        f.write("个人联系人管理系统导出数据\n")
        f.write("=" * 50 + "\n\n")
        for i, contact in enumerate(self.contacts, 1):
        f.write(f"联系人 {i}:\n")
        f.write(f"姓名: {contact['name']}\n")
        f.write(f"电话: {contact['phone']}\n")
        f.write(f"邮箱: {contact['email']}\n")
        f.write(f"地址: {contact['address']}\n")
        f.write("-" * 40 + "\n\n")
        print(f"联系人数据已导出到 {filename}")
        except Exception as e:
        print(f"导出失败: {e}")

        def import_contacts(self):
        filename = input("请输入要导入的文件名: ").strip()
        if not filename or not os.path.exists(filename):
        print("文件不存在!")
        return

        try:
        with open(filename, 'r', encoding='utf-8') as f:
        content = f.read().strip()
        if content:
        imported_contacts = json.loads(content)

        added_count = 0
        for contact in imported_contacts:
        if contact not in self.contacts:
        self.contacts.append(contact)
        added_count += 1

        self.save_contacts()
        print(f"成功导入 {added_count} 个新联系人!")
        else:
        print("文件为空!")
        except Exception as e:
        print(f"导入失败: {e}")

        def run(self):
        while True:
        print("\n" + "=" * 50)
        print("个人联系人管理系统")
        print("=" * 50)
        print("1. 添加联系人")
        print("2. 删除联系人")
        print("3. 修改联系人")
        print("4. 查找联系人")
        print("5. 显示所有联系人")
        print("6. 导出联系人")
        print("7. 导入联系人")
        print("0. 退出系统")
        print("-" * 50)

        choice = input("请选择操作 (0-7): ").strip()

        if choice == '1':
        self.add_contact()
        elif choice == '2':
        self.delete_contact()
        elif choice == '3':
        self.update_contact()
        elif choice == '4':
        self.search_contact()
        elif choice == '5':
        self.display_all_contacts()
        elif choice == '6':
        self.export_contacts()
        elif choice == '7':
        self.import_contacts()
        elif choice == '0':
        print("感谢使用个人联系人管理系统!")
        break
        else:
        print("无效选择，请重新输入!")

        if __name__ == "__main__":
        manager = ContactManager()
        manager.run()
    </div>

    <script>
        mermaid.initialize({ startOnLoad: true });
    </script>
</body>

</html>